package com.yonyou.wdt.job;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yonyou.wdt.entity.OpenApiURLEnum;
import com.yonyou.wdt.entity.QueryDto;
import com.yonyou.wdt.job.config.BaseConfig;
import com.yonyou.wdt.qimenmodel.qimencloud.api.DefaultQimenCloudClient;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.request.WdtStockOutDtlQueryRequest;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.request.WdtStockoutOrderQueryTradeRequest;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.response.WdtStockOutDtlQueryResponse;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.response.WdtStockoutOrderQueryTradeResponse;
import com.yonyou.wdt.service.YonsuiteService;
import com.yonyou.wdt.utils.DateUtils;
import com.yonyou.wdt.utils.ReSubmitUtil;
import com.yonyou.wdt.utils.WdtConfigProperties;
import com.yonyou.wdt.utils.YsQueryUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Component
public class WdtQmSaleOutToYsSaleOutJobNew extends BaseConfig {

	private static final Logger logger = LoggerFactory.getLogger(WdtQmSaleOutToYsSaleOutJobNew.class);
	private final WdtConfigProperties configProperties;
	@Resource
	private YonsuiteService yonsuiteService;
	private static final String JOB_CLASS="maoEr004";
	@Autowired
	public WdtQmSaleOutToYsSaleOutJobNew(WdtConfigProperties configProperties) {
		this.configProperties = configProperties;
	}
	
	@XxlJob("WdtQmSaleOutToYsSaleOutJobNew")
	public ReturnT<String> WdtQmSaleOutToYsSaleOutJobNew(String params) throws Exception {
		String param = XxlJobHelper.getJobParam();
		Map<String, Object> map = new HashMap<>();
		if (param != null && !"".equals(param)) {
			List<String> timeRange = Arrays.asList(param.split("\\|"));
			if (timeRange.size() == 2) {
				map.put("Start", timeRange.get(0));
				map.put("End", timeRange.get(1));
			} else {
				map.put("stockout_no", timeRange.get(0));
			}
		} else {
			// 默认查询前一天的数据
			map.put("Start", DateUtils.getStartDateBy10m());
			map.put("End", DateUtils.getEndDateBy10m());
		}
		String dateStr = null;
		if (map.get("stockout_no")==null){
			dateStr = map.get("Start").toString() + map.get("End").toString();
		}
		// 处理相关业务
		QueryDto dto = new QueryDto();
		dto.setTenantId(getYsTenantId());
		dto.setAppKey(getYsAppKey());
		dto.setAppSecret(getYsAppSecret());
		// 获取YS系统租户动态域名信息
		ReturnT<String> isReturn2 = getYsDynamicDomainName(JOB_CLASS,dto);
		// 域名获取失败
		if (isReturn2 != null) return isReturn2;
		try {
			// 根据客户查询旺店通店铺配置信息
			//自定义档案列表查询
			HashMap<String, String> custData = YsQueryUtil.getFhdpDef(dto,yonsuiteService);
			ArrayList<String> collect = new ArrayList<>();
			for (String s : custData.keySet()) {
				collect.add(custData.get(s));
			}
			String replace = collect.toString().replace("[", "").replace("]","").replace(" ","");
			map.put("shop_nos", replace);
			List<JSONObject> responseList = sendWdtByQm(map);
			// 解析数据，组装YS请求参数
				if (!responseList.isEmpty()) {
					ArrayList<Map<String, Object>> ysSaveParamList = new ArrayList<>();
					for (JSONObject jsonObject : responseList) {
						Map<String, Object> ysSaveParam = assembleYsParams(jsonObject);
						if (null != ysSaveParam) {
							ysSaveParamList.add(ysSaveParam);
						}
					}
					logger.info("当前时间段：{}至{} 需要同步到YS销售出库数据有：{}条", map.get("Start"), map.get("End"), ysSaveParamList.size());
					// 调用YS接口保存数据
					int index = 1;  // 记录执行次数处理接口调用频率问题
					for (Map<String, Object> paramMap : ysSaveParamList) {
						String wdtCode =JSONUtil.parseObj(paramMap.get("data")).getStr("code");
						JSONObject response = yonsuiteService.saleOutMergeSave(paramMap, dto);
						if (null != response && "200".equals(response.getStr("code")) && BigDecimal.ONE.compareTo(response.getJSONObject("data").getBigDecimal("sucessCount"))==0) {
							logger.info("旺店通2B销售出库单保存YS销售出库成功");
							String code = JSONUtil.parseObj(response.getJSONObject("data").getJSONArray("infos").get(0)).getStr("code");
							InsertLogger(JOB_CLASS,wdtCode, "1",  "旺店通2B销售出库单"+wdtCode+"保存YS销售出库"+code+"成功");
						} else {
							logger.error("旺店通2B销售出库单保存YS销售出库失败：{}", response.getJSONObject("data").getJSONArray("messages").toString());
							InsertLogger(JOB_CLASS,wdtCode, "0",  "旺店通2B销售出库单"+wdtCode+"保存YS销售出库失败"+ response.getJSONObject("data").getJSONArray("messages").toString());
						}
						this.APICurrentLimiting(OpenApiURLEnum.SALE_STOCK_OUT_MERGE_SOURCE_SAVE,59);
					}
				}
		} catch (Exception e) {
			logger.error("Error occurred", e);
			logger.error("旺店通2B销售出库单同步YS销售出库失败，{}", e.getMessage());
			InsertLogger(JOB_CLASS,null, "0",  "旺店通2B销售出库单保存YS销售出库失败"+e);
			return ReturnT.FAIL;
		}
		logger.info("  --  旺店通2B销售出库单同步YS销售出库任务执行完成  --  ");
		return ReturnT.SUCCESS;
	}
	
	/**
	 * @return
	 * @Author Huangwb
	 * @Description 组装YS请求数据
	 * @Date 14:34 2023/5/17
	 * @Param
	 **/
	private Map<String, Object> assembleYsParams(JSONObject jsonObject) throws Exception {
		Map<String, Object> data = new HashMap<>();
		Map<String, Object> body = new HashMap<>();
		// ==========主表============

		body.put("mergeSourceData",true);
		String bustyp="A30001";
		body.put("bustype", bustyp); // 交易类型id或编码
		body.put("warehouse", jsonObject.getStr("warehouse_no")); // 仓库id或编码
	/*	java.sql.Date date = new java.sql.Date(jsonObject.getLong("modified"));
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String time = formatter.format(date);*/
		body.put("vouchdate", jsonObject.getStr("stock_check_time").substring(0,10)); // 单据日期
		String wdtCode = jsonObject.getStr("order_no");
		body.put("code", wdtCode);
		body.put("_status", "Insert");
		body.put("cLogisticsBillNo", jsonObject.getStr("logistics_no"));
		JSONArray items = jsonObject.getJSONArray("details_list");
		// ==========子表============
		JSONArray details = new JSONArray();
		for (Object element : items) {
			JSONObject item = (JSONObject) element;
			JSONObject detailJSON = new JSONObject();
			String srcOid = item.getStr("src_oid");
			if (StringUtils.contains(srcOid, "_")) {
				String[] ids = StringUtils.split(srcOid, "_");
				if (ids.length >= 2) {
					//"2178619060972421121_2178619060972421123"
					detailJSON.put("sourceid",ids[0]);
					detailJSON.put("sourceautoid",ids[1]);
					/*detailJSON.put("sourceid","2178842416464265222");
					detailJSON.put("sourceautoid","2178842416464265223");*/
				}
			}else {
				InsertLogger(JOB_CLASS,wdtCode, "0",  "旺店通2B销售出库单"+wdtCode+"保存YS销售出库失败,不需要回传销售出库");
				return null;
			}
			detailJSON.put("batchno", StringUtils.isBlank(item.getStr("batch"))?"202412":item.getStr("batch"));
			detailJSON.put("invaliddate", StringUtils.isBlank(item.getStr("expire_date")) || item.getStr("expire_date").substring(0,10).equals("0000-00-00")?"2027-12-31":item.getStr("expire_date"));
			detailJSON.put("_status","Insert");
			detailJSON.put("qty",item.getBigDecimal("num"));
			detailJSON.put("makeRuleCode","deliveryTostoreout");
			details.add(detailJSON);
		}
		HashMap<String, Object> defHashMap = new HashMap<>();
		defHashMap.put("maoer04",jsonObject.getStr("logistics_name"));
		defHashMap.put("maoer03",jsonObject.getStr("shop_no"));
		defHashMap.put("maoer05",wdtCode);
		body.put("salesOutDefineCharacter",defHashMap);
		body.put("details", details);

		// 测试用过一些数据，可能会重新同步，防止幂等相同
	/*	body.put("resubmitCheckKey", jsonObject.getStr("order_no")+22);
		ReSubmitUtil.resubmitCheckKey(body);*/
		data.put("data", body);
		return data;
	}
	private List<JSONObject> sendWdtByQm(Map<String, Object> map) {
		List<JSONObject> resList = new ArrayList<>();
		DefaultQimenCloudClient client = new DefaultQimenCloudClient(configProperties.getQmServerUrl(), configProperties.getQmAppKey(), configProperties.getQmAppSecret(), "json");
		Integer realityPageNo = 0;
		map.put("page_no", realityPageNo.toString());
		map.put("page_size", "100");
//		map.put("status", 110);
		boolean hasNext = true;
		//总页数
		Integer totalPage = 0;
		//总条数
		Integer total_count = 0;
		String consign_time = null;
		try {
			while (hasNext) {
				map.put("page_no", realityPageNo.toString());
				WdtStockoutOrderQueryTradeRequest req = this.setModel(map, configProperties.getQmTargetAppKey(), configProperties.getSid());
				WdtStockoutOrderQueryTradeResponse res = null;
				try {
					res = client.execute(req);
				} catch (com.yonyou.wdt.qimenmodel.taobao.api.ApiException e) {
					throw new RuntimeException(e);
				}
				JSONObject saleOutJson = JSONUtil.parseObj(res.getBody()).getJSONObject("response");
				if ("0".equals(saleOutJson.getStr("errorcode"))) {
					//判断分页
					if (realityPageNo == 0) {
						total_count = saleOutJson.getInt("total_count", 0);
						totalPage = total_count % 100 == 0 ? total_count / 100 : total_count / 100 + 1;
					}
					//每页订单列表
					JSONArray orderArray = saleOutJson.getJSONArray("stockout_list");
					if (orderArray.size() > 0) {
						//resList.addAll(JSONUtil.toList(orderArray,JSONObject.class));
						List<JSONObject> list = JSONUtil.toList(orderArray, JSONObject.class);
						for (JSONObject entries : list) {
							ArrayList<JSONObject> dtlList = new ArrayList<>();
							HashMap<String, Object> stringObjectHashMap = new HashMap<>();
							String stockOutNo = entries.getStr("order_no");
							stringObjectHashMap.put("stockout_no",stockOutNo);
							Boolean flag=true;
							Integer dtlTotalCount=0;
							Integer dtlTotalPage=0;
							Integer dtlRealityPageNo = 0;
							while (flag){
								stringObjectHashMap.put("page_no",dtlRealityPageNo.toString());
								stringObjectHashMap.put("page_size",100);
								WdtStockOutDtlQueryRequest dtlReq = this.setStockOutDtlModel(stringObjectHashMap, configProperties.getQmTargetAppKey(), configProperties.getSid());
								WdtStockOutDtlQueryResponse dtlRes = null;
								try {
									dtlRes = client.execute(dtlReq);
								} catch (com.yonyou.wdt.qimenmodel.taobao.api.ApiException e) {
									throw new RuntimeException(e);
								}
								JSONObject dtlJson = JSONUtil.parseObj(dtlRes.getBody()).getJSONObject("response");
								if ("0".equals(dtlJson.getStr("errorcode"))) {
									//判断分页
									if (dtlRealityPageNo == 0) {
										dtlTotalCount = dtlJson.getInt("total_count", 0);
										dtlTotalPage = dtlTotalCount % 100 == 0 ? dtlTotalCount / 100 : dtlTotalCount / 100 + 1;
									}
									//每页订单列表
									JSONArray dtlJosn = dtlJson.getJSONArray("stockout_batch_detail");
									dtlList.addAll(JSONUtil.toList(dtlJosn,JSONObject.class));
								}else {
									InsertLogger(JOB_CLASS,stockOutNo, "0", "旺店通出库批次接口查询失败" + dtlJson.getStr("message"));
									break;
								}
								this.APICurrentLimiting("wdt.stockout.batch.detail",59);
								if (dtlTotalPage > dtlRealityPageNo + 1) {
									dtlRealityPageNo += 1;
								} else {
									flag = false;
								}
							}


							JSONArray jsonArray = entries.getJSONArray("details_list");
							JSONArray newDetail = new JSONArray();
							for (Object obj : jsonArray) {
								JSONObject entries1 = JSONUtil.parseObj(obj);
								Optional<JSONObject> any = dtlList.stream().filter(o -> o.getStr("goods_no").equals(entries1.getStr("goods_no"))).findAny();
								if (any.isPresent()){
									entries1.set("batch",any.get().getStr("batch"));
									String substring = any.get().getStr("expire_date").substring(0, 10);
									if (!substring.equals("0000-00-00")){
										entries1.set("expire_date", substring);
									}else {
										entries1.set("expire_date", "");
									}
								}
								newDetail.add(entries1);
							}
							entries.set("details_list",newDetail);
							resList.add(entries);
						}
					}
					//判断分页
					if (realityPageNo == 0) {
						total_count = saleOutJson.getInt("total_count", 0);
						totalPage = total_count % 100 == 0 ? total_count / 100 : total_count / 100 + 1;
					}
					this.APICurrentLimiting("wdt.stockout.order.query.trade",59);
					if (totalPage > realityPageNo + 1) {
						realityPageNo += 1;
					} else {
						hasNext = false;
					}
				} else {
					InsertLogger(JOB_CLASS,null, "0", "旺店通销售出库接口查询失败" + saleOutJson.getStr("sub_message"));
					break;
				}
			}
		} catch (Exception e) {
			logger.error("Error occurred", e);
			logger.error("查询旺店通退货入库单失败：【{}】", e.getMessage());
		}
		return resList;
	}
	public WdtStockoutOrderQueryTradeRequest setModel(Map param, String targetAppKey, String sid) {
		WdtStockoutOrderQueryTradeRequest req = new WdtStockoutOrderQueryTradeRequest();
		//旺店通的奇门appkey
		req.setTargetAppKey(targetAppKey);
		//旺店通erp的卖家账号
		req.setSid(sid);
		String startTime = MapUtil.getStr(param, "Start");
		if (StringUtils.isNotBlank(startTime)) {
			req.setStartTime(startTime);
		}
		String endTime = MapUtil.getStr(param, "End");
		if (StringUtils.isNotBlank(endTime)) {
			req.setEndTime(endTime);
		}
		Long status = MapUtil.getLong(param, "status");
		if (status != null) {
			req.setStatus(status);
		}
		String srcOrderNo = MapUtil.getStr(param, "src_order_no");
		if (StringUtils.isNotBlank(srcOrderNo)) {
			req.setSrcOrderNo(srcOrderNo);
		}
		String srcTid = MapUtil.getStr(param, "src_tid");
		if (StringUtils.isNotBlank(srcTid)) {
			req.setSrcTid(srcTid);
		}
		String stockoutNo = MapUtil.getStr(param, "stockout_no");
		if (StringUtils.isNotBlank(stockoutNo)) {
			req.setStockoutNo(stockoutNo);
		}
		if (param.containsKey("page_no")) {
			req.setPageNo(MapUtil.getLong(param, "page_no"));
		}
		if (param.containsKey("page_size")) {
			req.setPageSize(MapUtil.getLong(param, "page_size"));
		}
		Integer isByModified = MapUtil.getInt(param, "is_by_modified");
		if (isByModified != null) {
			req.setIsByModified(isByModified);
		}
		String shop_no = MapUtil.getStr(param, "shop_no");
		if (StringUtils.isNotBlank(shop_no)) {
			req.setShopNo(shop_no);
		}
		if (param.containsKey("shop_nos")) {
			req.setShopNos(MapUtil.getStr(param, "shop_nos"));
		}
		String warehouseNo = MapUtil.getStr(param, "warehouse_no");
		if (StringUtils.isNotBlank(warehouseNo)) {
			req.setWarehouseNo(warehouseNo);
		}
		Integer isNoPosition = MapUtil.getInt(param, "is_no_position");
		if (isNoPosition != null) {
			req.setIsNoPosition(isNoPosition);
		}
		return req;
	}
}
